import fs from "fs";
const PATH = require('path');
import { config, env } from '../../config';
import xlsx from 'xlsx';

class xlsxToJson {
    constructor() {

    }
    async init() {
        if (env.DEV) {
            await this.refData();
        } else {
            await this.refConfig();
        }
    }
    // 生产环境
    async refConfig() {
        console.log(PATH.resolve(__dirname, '../config'));
        let paths = fs.readdirSync(PATH.resolve(__dirname, '../config'));
        paths.forEach(fileName => {
            if (fileName.endsWith('.json')) {
                const filePath = PATH.resolve(__dirname, '../config', fileName);
                const fileContent = fs.readFileSync(filePath, 'utf-8');
                const jsonData = JSON.parse(fileContent);
                let map = new Map();
                jsonData.forEach((item: any) => {
                    map.set(item.id, item);
                });
                config.set(`${fileName.split('.')[0]}`, map)
            }
        });
    }
    // 开发环境
    refData() {
        let paths = fs.readdirSync(PATH.resolve('./xlsx/'))
        for (let j = 0; j < paths.length; j++) {
            const fileName = paths[j];
            const workBook = xlsx.readFile(PATH.resolve('./xlsx/', fileName));
            if (fileName.includes('~')) {
                continue;
            }
            for (let index = 0; index < workBook.SheetNames.length; index++) {
                const name = workBook.SheetNames[index];
                if (name.includes('~')) {
                    continue;
                }
                let sheet = workBook.Sheets[name]

                this.deleteRow(sheet, 0)
                let _outData = xlsx.utils.sheet_to_json(sheet) as Array<any>;
                let typeKey = _outData[0];
                let outData: Map<string, any> = new Map();
                for (let i = 1; i < _outData.length; i++) {
                    const item = _outData[i];
                    let outItem = {} as any;
                    for (const key in typeKey) {
                        let reKey = key;
                        const typeStr = typeKey[key];
                        const itemTypeStr = typeof (item[key]);
                        if (itemTypeStr == 'undefined' && !item[key]) {
                            if (key == 'id') {
                                outItem = undefined;
                                break;
                            }
                            if (key.includes('_')) {
                                continue;
                            }
                            switch (typeKey[key]) {
                                case 'String':
                                    item[key] = '';
                                    break;
                                case 'Num':
                                    item[key] = 0;
                                    break;
                                case 'Json':
                                    item[key] = '{}';
                                    break;
                                case 'Json2':
                                    item[key] = '';
                                    break;
                                default:
                                    break;
                            }
                        }

                        try {
                            if (itemTypeStr != typeStr) {
                                if (key.includes('_')) {
                                    let reKey = key.split('_')[0];
                                    if(typeKey[reKey] == 'Json2'){
                                        let _obj = {} as any;
                                        let _str2 = item[key] as string;
                                        let _str2Parts = _str2.split('\n');
                                        _str2Parts.forEach(part => {
                                            let kv = part.split('=');
                                            if(kv[1] == undefined){
                                                return;
                                            }
                                            _obj[kv[0]] = kv[1];
                                        });
                                        if(!outItem[reKey]){
                                            outItem[reKey] = [_obj];
                                        }else{
                                            if(Array.isArray(outItem[reKey])){
                                                outItem[reKey].push(_obj);
                                            }else{  
                                                outItem[reKey] = [outItem[reKey],_obj];
                                            }
                                        }
                                    }else{
                                        if(!outItem[reKey]){
                                            outItem[reKey] = [item[key].toString()];
                                        }else{
                                            if(Array.isArray(outItem[reKey])){
                                                if(typeKey[key] == 'Num'){
                                                    outItem[reKey].push(parseFloat(item[key]));
                                                }else{
                                                    outItem[reKey].push(item[key].toString());
                                                }
                                                
                                            }else{  

                                                if(typeKey[key] == 'Num'){
                                                    outItem[reKey] = [outItem[reKey],parseFloat(item[key])];
                                                }else{
                                                    outItem[reKey] = [outItem[reKey],item[key].toString()];
                                                }
                                               
                                            }
                                        }
                                    }
                                  
                                    continue;
                                }
                                switch (typeKey[key]) {
                                    case 'String':
                                        item[key] = item[key].toString();
                                        break;
                                    case 'Num':
                                        item[key] = parseFloat(item[key]);
                                        break;
                                    case 'Json':
                                        let _str = item[key] as string;
                                        _str = _str.replace(/'/g, '"');
                                        try {
                                            item[key] = JSON.parse(_str)
                                        } catch (error) {
                                            debugger
                                        }
                                        break;
                                    case 'Json2':
                                        let _obj = {} as any;
                                        let _str2 = item[key] as string;
                                        let _str2Parts = _str2.split('\n');
                                        _str2Parts.forEach(part => {
                                            let kv = part.split('=');
                                            if(kv[1] == undefined){
                                                return;
                                            }
                                            _obj[kv[0]] = kv[1];
                                        });
                                        item[key] = _obj;
                                        break;
                                    default:
                                        break;
                                }
                            }
                        } catch (error) {
                            debugger
                        }
                        outItem[key] = item[key]
                    }
                    if (outItem) {
                        outData.set(outItem.id, outItem)
                    }
                }
                let outFileName = `${fileName.split('.')[0]}_${name}`;
                const dir = PATH.resolve(__dirname, '../config');
                if (!fs.existsSync(dir)) {
                    fs.mkdirSync(dir);
                }
                const jsonObject = Array.from(outData.values());
                fs.writeFileSync(`${dir}/${outFileName}.json`, JSON.stringify(jsonObject, null, 2), { flag: 'w' });
                config.set(`${fileName.split('.')[0]}_${name}`, outData)
                // app.setXlsxCfg(name, outData)
            }
        }
    }
    private encodeCell(r: any, c: any) {
        return xlsx.utils.encode_cell({ r, c });
    }

    private deleteRow(ws: any, index: number) {
        const range = xlsx.utils.decode_range(ws['!ref']);

        for (let row = index; row < range.e.r; row++) {
            for (let col = range.s.c; col <= range.e.c; col++) {
                ws[this.encodeCell(row, col)] = ws[this.encodeCell(row + 1, col)];
            }
        }

        range.e.r--;

        ws['!ref'] = xlsx.utils.encode_range(range.s, range.e);
    }
}
export default new xlsxToJson();